#include "GraphicsEngine.hpp"

//--------------------- Graphics engine ---------------------

//-------------- Private --------------

//------- FPS -------
void GraphicEngine::initCalculateFPS()
{
    frameCount = 0;
    fps = 0;
    currentTime = 0;
    previousTime = 0;

    strcpy(cfps,"FPS: ");
}

void GraphicEngine::calculateFPS()
{
    frameCount++;

    currentTime = glutGet(GLUT_ELAPSED_TIME);

    timeInterval = currentTime - previousTime;

    if(timeInterval > 100)
    {
        fps = frameCount / (timeInterval / 1000.0f);

        previousTime = currentTime;

        frameCount = 0;

        sprintf(&cfps[5],"%f",fps);
    }
}

//------- GLFW -------
int GraphicEngine::initWinodw()
{
    // Initialise GLFW
    if( !glfwInit() )
    {
        cout << "Failed to initialize GLFW\n" << endl;
        return 0;
    }

    glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Open a window and create its OpenGL context
    if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW ) )
    {
        cout << "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" << endl;
        glfwTerminate();
        return 0;
    }

    // Initialize GLEW
    glewExperimental = true;
    if (glewInit() != GLEW_OK)
    {
        cout << "Failed to initialize GLEW\n" << endl;
        return 0;
    }

    glfwSetWindowTitle( "World!" );

    // Ensure we can capture the escape key being pressed below
    glfwEnable( GLFW_STICKY_KEYS );

    glfwGetMouseWheel();


    glEnable(GL_DEPTH_TEST);
    //glDepthFunc(GL_LESS);

    // Dark blue background
    glClearColor(0.1f, 0.0f, 0.15f, 0.0f);

    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Initialize our little text library with the Holstein font
    initText2D( "Holstein.tga" );

    return 1;
}

//------- Buttons -------
void GraphicEngine::buttons(WavefrontOBJ &obj){
    if(glfwGetKey( 49 ) == GLFW_PRESS && light)
    {
        obj.lightChange();

        light = false;
    }else if(!light && !glfwGetKey( 49 ) == GLFW_PRESS){
        light = true;
    }

    if(glfwGetKey( 50 ) == GLFW_PRESS && cameraLight)
    {
        obj.cameraLightChange();

        cameraLight = false;
    }else if(!cameraLight && !glfwGetKey( 50 ) == GLFW_PRESS){
        cameraLight = true;
    }

    if(glfwGetKey( 51 ) == GLFW_PRESS && noise)
    {
        obj.noiseChange();

        noise = false;
    }else if(!noise && !glfwGetKey( 51 ) == GLFW_PRESS){
        noise = true;
    }

    if(glfwGetKey( 52 ) == GLFW_PRESS && texture)
    {
        obj.textureChange();

        texture = false;
    }else if(!texture && !glfwGetKey( 52 ) == GLFW_PRESS){
        texture = true;
    }
}

//-------------- Public --------------
GraphicEngine::GraphicEngine()
{
    initWinodw();
    initCalculateFPS();
}

void GraphicEngine::graphicEngineLoop(string name)
{
    mat4 VP;
    mat4 V;

    vec3 camerePosition;

    WavefrontOBJ obj(("objects/" + name + "/"), (name + ".obj"));

    do
    {
        calculateFPS();

        computeMatricesFromInputs(fps);
        V = getViewMatrix();
        VP = getProjectionMatrix() * V;
        camerePosition = getPosition();

        //Clear the screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        obj.draw(VP, V, camerePosition);

        printText2D(cfps, 10, 580, 10);

        buttons(obj);

        // Swap buffers
        glfwSwapBuffers();
    }
    while(  glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
             glfwGetWindowParam( GLFW_OPENED ) );
}
